package dk.dtu.is.gui;

import java.awt.*;
import java.awt.event.*;
import java.io.File;

import javax.swing.*;

import org.apache.batik.swing.*;
import org.apache.batik.swing.svg.SVGLoadEventDispatcherAdapter;
import org.apache.batik.swing.svg.SVGLoadEventDispatcherEvent;
import org.apache.batik.script.Window;
import org.apache.batik.dom.svg.SVGOMAElement;
import org.apache.batik.dom.svg.SVGOMDocument;
import org.apache.batik.dom.svg.SVGOMRectElement;

public class MainWindow implements ActionListener {
	
	private enum Colors {
		RED("ff0000"), YELLOW("f9e81f"), GREEN("61c74f"), BLUE("0d6cff"), VIOLET("a100ff"), WHITE("ffffff");
		private String value;
		private Colors (String value){
		this.value = value;}
	}
	
	private JFrame frame;
	private JPanel panel;
	private JSVGCanvas cellCanvas;
	private JSVGCanvas socCanvas;
	private JSVGCanvas legendCanvas;

	private SVGOMDocument cellDocument;
	private SVGOMDocument socDocument;

	private JList statusList;
	private DefaultListModel statusListModel;

	private boolean cellSVGLoaded = false;

	public boolean isCellSVGLoaded() {
		return cellSVGLoaded;
	}

	public void setCellSVGLoaded(boolean cellSVGLoaded) {
		this.cellSVGLoaded = cellSVGLoaded;
	}

	private boolean socSVGLoaded = false;

	public boolean isSocSVGLoaded() {
		return socSVGLoaded;
	}

	public void setSocSVGLoaded(boolean socSVGLoaded) {
		this.socSVGLoaded = socSVGLoaded;
	}

	public MainWindow() {
		makeFrame();
	}

	@SuppressWarnings("serial")
	public class SelectedListCellRenderer extends DefaultListCellRenderer {
		@Override
		public Component getListCellRendererComponent(JList list, Object value,
				int index, boolean isSelected, boolean cellHasFocus) {
			Component c = super.getListCellRendererComponent(list, value,
					index, isSelected, cellHasFocus);
			String tmpValue = value.toString().toLowerCase();
			if ((tmpValue.contains("critical") && tmpValue.contains("low"))||tmpValue.contains("error")) {
				c.setBackground(Color.RED);
			} else if (tmpValue.contains("warning")||tmpValue.contains("low")) {
				c.setBackground(Color.YELLOW);
			} else if (tmpValue.contains("ok")) {
				c.setBackground(Color.GREEN);
			} else if (!tmpValue.contains("critical")&&tmpValue.contains("high")) {
				c.setBackground(Color.BLUE);
			} else if (tmpValue.contains("critical")&&tmpValue.contains("high")) {
				c.setBackground(Color.PINK);
			} else{
				//do nothing
			}
			return c;
		}
	}

	public void actionPerformed(ActionEvent event) {
		System.out.println("Item: " + event.getActionCommand());
	}

	/**
	 * Quit function: quit the application.
	 */
	private void quit() {
		System.exit(0);
	}

	private void about() {
		JDialog aboutDialog = new JDialog(frame, "About");
		JLabel aboutLabel = new JLabel("Created by GES");
		aboutDialog.add(aboutLabel);
		aboutDialog.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		aboutDialog.pack();
		aboutDialog.setLocationRelativeTo(frame);
		aboutDialog.setVisible(true);
	}

	private void makeFrame() {
		frame = new JFrame();

		frame.setTitle("PowerLabDK Client GUI");
		frame.setSize(800, 600); // default size is 0,0
		frame.setLocation(0, 0); // default is 0,0 (top left corner)
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		cellCanvas = new JSVGCanvas();
		socCanvas = new JSVGCanvas();
		legendCanvas = new JSVGCanvas();

		panel = new JPanel(new BorderLayout());

		// Java scroll list
		statusListModel = new DefaultListModel();

		statusList = new JList(statusListModel);
		statusList.setCellRenderer(new SelectedListCellRenderer());
		JScrollPane historyScrollPane = new JScrollPane(statusList);
		historyScrollPane.setPreferredSize(new Dimension(800, 80));
		historyScrollPane.setAutoscrolls(true);

		panel.add(historyScrollPane, BorderLayout.NORTH);

		// JSVGCanvas
		cellCanvas.setDocumentState(JSVGCanvas.ALWAYS_DYNAMIC);
		cellCanvas
				.addSVGLoadEventDispatcherListener(new SVGLoadEventDispatcherAdapter() {
					public void svgLoadEventDispatchStarted(
							SVGLoadEventDispatcherEvent e) {
						// At this time the document is available...
						cellDocument = (SVGOMDocument) cellCanvas
								.getSVGDocument();
						// ...and the window object too.
						registerCellListeners();
					}
				});
		panel.add(cellCanvas, BorderLayout.CENTER);
		File f = new File("media/cell_panel.svg");
		cellCanvas.setURI(f.toURI().toString());
		cellCanvas.setPreferredSize(new Dimension(600, 400));

		// JSVGCanvas
		socCanvas.setDocumentState(JSVGCanvas.ALWAYS_DYNAMIC);
		socCanvas
				.addSVGLoadEventDispatcherListener(new SVGLoadEventDispatcherAdapter() {
					public void svgLoadEventDispatchStarted(
							SVGLoadEventDispatcherEvent e) {
						// At this time the document is available...
						socDocument = (SVGOMDocument) socCanvas.getSVGDocument();
						
//						window = (Window) socCanvas.getUpdateManager();
						// ...and the window object too.
						registerSOCListeners();
					}
				});
		panel.add(socCanvas, BorderLayout.EAST);
		f = new File("media/batterygood.svg");
		socCanvas.setURI(f.toURI().toString());

		// JSVGCanvas

		panel.add(legendCanvas, BorderLayout.SOUTH);
		f = new File("media/legendgood.svg");
		legendCanvas.setURI(f.toURI().toString());
		legendCanvas.setPreferredSize(new Dimension(800, 60));

		frame.add(panel);
		// make menu bar
		makeMenuBar(frame);
		frame.pack();
		frame.setVisible(true);
		statusListModel.addElement("GUI Started");
	}

	protected void registerCellListeners() {
		cellSVGLoaded = true;
		// Gets an element from the loaded document.

		System.out.println("Cell SVG Loaded");
		// cellDocument.getElementById("cell-1-1").setAttribute("width", "30");
//		this.updateCell("Cell voltage critically low", 1, 5);
//		this.updateCell("Cell voltage difference high", 5, 8);
//		this.updateCell("Cell voltage difference ok", 5, 7);
	}

	protected void registerSOCListeners() {
		socSVGLoaded = true;
		// Gets an element from the loaded document.
		System.out.println("SOC SVG Loaded");
//		this.updateBatterySOC(75);
	}

	private void makeMenuBar(JFrame frame) {
		JMenuBar menubar = new JMenuBar();
		frame.setJMenuBar(menubar);

		// creating File menu
		JMenu fileMenu = new JMenu("File");
		menubar.add(fileMenu);

		JMenuItem quitItem = new JMenuItem("Exit");
		quitItem.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				quit();
			}
		});
		fileMenu.add(quitItem);

		// creating Help menu
		JMenu helpMenu = new JMenu("Help");
		menubar.add(helpMenu);

		JMenuItem aboutItem = new JMenuItem("About");
		aboutItem.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				about();
			}
		});
		helpMenu.add(aboutItem);
	}

	public void updateBatterySOC(double SOC) {
		if (socSVGLoaded) {
			this.updateBattery(SOC);
			socDocument.getElementById("soc_label").setTextContent(new String(Integer.toString((int)SOC)+"%"));
			System.out.println("Battery SoC updated to " + SOC);
		} else {
			System.out.println("GUI not loaded");
		}
	}
	
	private void updateBattery(double SOC) {
		String style = new String();
		for(int i=1;i<11;i++)
		{
			String elementId = new String("pct" + Integer.toString(i*10));
			style = socDocument.getElementById(elementId).getAttribute("style");
			if(i*10>SOC)
			{
				style = style.replaceFirst(style.substring(6, 12), Colors.WHITE.value);
			} else
			{
				if (SOC<20){
					style = style.replaceFirst(style.substring(6, 12), Colors.RED.value);
				}else if(SOC>20 && SOC<30 ){
					style = style.replaceFirst(style.substring(6, 12), Colors.YELLOW.value);
				}else if(SOC>30 && SOC<80){
					style = style.replaceFirst(style.substring(6, 12), Colors.GREEN.value);
				}else if(SOC>80 && SOC<90){
					style = style.replaceFirst(style.substring(6, 12), Colors.BLUE.value);
				}else if(SOC>90){
					style = style.replaceFirst(style.substring(6, 12), Colors.VIOLET.value);
				}
			}
			socDocument.getElementById(elementId).setAttribute("style", style);
		}
	}

	public boolean isGUILoaded() {
		return (this.socSVGLoaded & this.cellSVGLoaded);
	}

	public void refreshGUI() {
		cellCanvas.repaint();
		socCanvas.repaint();
		panel.repaint();
		frame.repaint();
		cellCanvas.validate();
		socCanvas.validate();
		panel.validate();
		frame.validate();
	}

	public void addStatusListItem(String item) {
		DefaultListModel tmpList = (DefaultListModel) statusList.getModel();
		tmpList.addElement(item);
		statusList.setModel(tmpList);
		System.out.println(item);
	}

	public void addStatusListItem(String item, int index) {
		DefaultListModel tmpList = (DefaultListModel) statusList.getModel();
		tmpList.add(index, item);
		statusList.setModel(tmpList);
		System.out.println(item);
	}

	public void removeStatusListItem(String item) {
		DefaultListModel tmpList = (DefaultListModel) statusList.getModel();
		if (tmpList.removeElement(item))
			System.out.println("Removed: "+item);
		statusList.setModel(tmpList);
	}

	public void removeStatusListItem(int index) {
		DefaultListModel tmpList = (DefaultListModel) statusList.getModel();
		tmpList.removeElementAt(index);
		System.out.println("Removed item at: "+index);
		statusList.setModel(tmpList);
	}

	public void updateCurrentLabel(double current) {
		if (socSVGLoaded) {
			socDocument.getElementById("current_label").setTextContent(new String(String.format("%.1f", current) + "A"));
			System.out.println("Battery Current updated to " + current);
		} else {
			System.out.println("GUI not loaded");
		}
	}

	public void updateVoltageLabel(double voltage) {
		if (socSVGLoaded) {
			socDocument.getElementById("voltage_label").setTextContent(new String(String.format("%.1f", voltage) + "V"));
			System.out.println("Battery Voltage updated to " + voltage);
		} else {
			System.out.println("GUI not loaded");
		}
	}
	
	public void updateStatusLabel(String status) {
		if (socSVGLoaded) {
			socDocument.getElementById("status_label").setTextContent(status);
			System.out.println("Battery Status updated to " + status);
		} else {
			System.out.println("GUI not loaded");
		}
	}
	
	public void emptyStatusList() {
		statusList.removeAll();
		statusList.setModel(new DefaultListModel());
	}
	
	public void updateCell(String message, int node, int id) {
		SVGOMRectElement elm;
		if (cellSVGLoaded) {
			elm = (SVGOMRectElement) cellDocument.getElementById("cell-1-1");
			for(int i=0;i<((node-1)*10 +id-1);i++)
			{
				elm = (SVGOMRectElement) elm.getNextElementSibling();
			}
			String style = elm.getAttribute("style");
			String tmpValue = message.toLowerCase();
			String color = elm.getAttribute("style").substring(6, 12);
			if ((tmpValue.contains("critical") && tmpValue.contains("low"))||tmpValue.contains("error")) {
				color = Colors.RED.value;
			} else if (tmpValue.contains("warning")||tmpValue.contains("low")) {
				color = Colors.YELLOW.value;
			} else if (tmpValue.contains("ok")) {
				color = Colors.GREEN.value;
			} else if (!tmpValue.contains("critical")&&tmpValue.contains("high")) {
				color = Colors.BLUE.value;
			} else if (tmpValue.contains("critical")&&tmpValue.contains("high")) {
				color = Colors.VIOLET.value;
			} else {
				
			}
			if (tmpValue.contains("difference")){
				//do nothing
				style = style.substring(0, 26) + "0.5" + style.substring(27);
			} else
			{
				style = style.substring(0, 26) + "1" + style.substring(27);
			}
			style = style.replaceFirst(style.substring(6, 12), color);
			elm.setAttribute("style", style);
		} else {
			System.out.println("GUI not loaded");
		}
	}
	

	public static void main(String[] args) {
		MainWindow window = new MainWindow();
	}
}